import { v4 as uuidv4 } from 'uuid'
import { coordinateUtils } from '../utils/index.js'

export default {
  add3DTileset,
  addPointPrimitives
}
/**
 * 添加倾斜摄影模型
 * @param {String} config.url 模型地址
 * @param {radians} config.RotateX 需要旋转的弧度 Cesium.Math.toRadians(0)
 * @param {radians} config.RotateY 需要旋转的弧度 Cesium.Math.toRadians(0)
 * @param {radians} config.RotateZ 需要旋转的弧度 Cesium.Math.toRadians(0)
 * @returns 
 */
function add3DTileset (config) {
  const {
    RotateX,
    RotateY,
    RotateZ,
    modelMatrix,
    skipLevels,
    skipLevelOfDetail, // 是否跳过细节级别（LOD）计算
    baseScreenSpaceError, // 基础屏幕空间误差，用于控制瓦片的细化程度
    skipScreenSpaceErrorFactor, // 跳过的屏幕空间误差因子
    immediatelyLoadDesiredLevelOfDetail, // 是否立即加载所需的细节级别
    loadSiblings, // 是否加载兄弟瓦片以减少闪烁
    cullWithChildrenBounds,
    progressiveResolutionHeightFraction,
    dynamicScreenSpaceErrorDensity,//动态屏幕空间误差密度
    maximumScreenSpaceError
  } = config || {}
  //会有高程遮挡效果
  this.viewer.scene.globe.depthTestAgainstTerrain = true
  //将视图模型对象的属性转化为监控属性
  Cesium.knockout.track({ height: 0 })

  let matrix4 = [
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
  ]
  if (RotateX) { // 绕X轴的旋转
    const cos_rotateX = Math.cos(RotateX)
    const sin_rotateX = Math.sin(RotateX)
    const rotateXMatrix4 = [
      1, 0, 0, 0,
      0, cos_rotateX, sin_rotateX, 0,
      0, -sin_rotateX, cos_rotateX, 0,
      0, 0, 0, 1
    ]
    matrix4 = Cesium.Matrix4.multiply(
      matrix4,
      rotateXMatrix4,
      new Cesium.Matrix4()
    )
  }
  if (RotateY) { // 绕Y轴旋转
    const cos_rotateY = Math.cos(RotateY)
    const sin_rotateY = Math.sin(RotateY)
    const rotateYMatrix4 = [
      cos_rotateY, 0, -sin_rotateY, 0,
      0, 1, 0, 0,
      sin_rotateY, 0, cos_rotateY, 0,
      0, 0, 0, 1
    ]
    matrix4 = Cesium.Matrix4.multiply(
      matrix4,
      rotateYMatrix4,
      new Cesium.Matrix4()
    )
  }
  if (RotateZ) { // 绕z轴的旋转
    const cos_rotateZ = Math.cos(RotateZ)
    const sin_rotateZ = Math.sin(RotateZ)
    const rotateZMatrix4 = [
      cos_rotateZ, sin_rotateZ, 0, 0,
      -sin_rotateZ, cos_rotateZ, 0, 0,
      0, 0, 1, 0,
      0, 0, 0, 1
    ]
    matrix4 = Cesium.Matrix4.multiply(
      matrix4,
      rotateZMatrix4,
      new Cesium.Matrix4()
    )
  }
  const options = {
    url,
    skipLevelOfDetail,
    baseScreenSpaceError,
    skipScreenSpaceErrorFactor,
    skipLevels,
    immediatelyLoadDesiredLevelOfDetail,
    loadSiblings,
    cullWithChildrenBounds,
    progressiveResolutionHeightFraction,
    dynamicScreenSpaceErrorDensity,
    maximumScreenSpaceError
  }
  modelMatrix && Object.assign(options, { modelMatrix })
  const tileset = new Cesium.Cesium3DTileset(options)

  tileset.readyPromise.then((tileset) => {
    this.viewer.scene.primitives.add(tileset)
    const headPitchRange = new Cesium.HeadingPitchRange(
      0.0,
      -0.5,
      tileset.boundingSphere.radius * 2.0
    )
    //地图定位到模型所在位置
    this.viewer.zoomTo(tileset, headPitchRange)
  })
  return tileset
}
/**
 * 添加点云数据
 * @param {Array} points 点位数据
 * @returns 
 */
function addPointPrimitives (points = []) {
  // 创建点云集合对象
  const pointPrimitives = new Cesium.PointPrimitiveCollection()
  this.viewer.scene.primitives.add(pointPrimitives)

  points.forEach(point => {
    const {
      id = uuidv4(),
      coordinate = [],// 经纬度
      color,// 内部颜色
      outlineColor, //点的轮廓颜色
      outlineWidth, //轮廓宽度
      size: pixelSize = 5, //大小
      show = true // 是否将显示此点
    } = point
    if (!coordinate.length) {
      throw Error('addPointPrimitives: coordinate is required')
    }
    const [lng, lat, alt = 0] = coordinate
    const position = coordinateUtils.lnglatToCartesian3(lng, lat, alt)
    // 创建点云对象
    const pointPrimitive = new Cesium.PointPrimitive({
      id,
      position,
      color: Cesium.Color.fromCssColorString(color),
      pixelSize,
      outlineColor,
      outlineWidth,
      show
    })
    pointPrimitives.add(pointPrimitive)
  })
  return pointPrimitives
}